﻿using System;

namespace Borg.Framework
{
    public class SelectComboBox : ComboBox, IAttachable
    {
        public SelectComboBox()
        {
            Enabled = false;
        }

        private void Add(PlugInfo pi)
        {
            object extensionInfo;

            if (pi.ExtensionInfo.Object is IObjectInfo)
                extensionInfo = pi.ExtensionInfo.Object;
            else
                extensionInfo = pi.ExtensionInfo;

            Items.Add(pi, extensionInfo);
        }

        public void Attach(SlotInfo slot)
        {
            Slot = slot;
            
            Slot.Plugged += Plugged;
            Slot.Unplugged += Unplugged;
            Slot.SelectionChanged += SelectionChanged;

            if (Runtime.IsCompositionAllowed)
                Slot.SelectionMode = SelectionMode.Single;

            Items.Clear();

            foreach (var plug in Slot.PluggedPlugInfos)
                Add(plug);
            if (Items.Count > 0 && Slot.SelectedPlug != null)
                SelectedKey = Slot.SelectedPlug;

            Enabled = true;
        }

        public void Detach()
        {
            Enabled = false;
            
            Slot.Plugged -= Plugged;
            Slot.Unplugged -= Unplugged;
            Slot.SelectionChanged -= SelectionChanged;
            
            Items.Clear();
            Slot = null;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (Slot != null)
                Detach();
        }

        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            base.OnSelectedIndexChanged(e);

            if (noUpdate)
                return;

            noUpdate = true;
            Slot.SelectedPlug = (PlugInfo)SelectedItem.Key;
            noUpdate = false;
        }

        private void Plugged(object sender, PlugEventArgs args)
        {
            Add(args.PlugInfo);
        }

        private void SelectionChanged(object sender, SelectionChangedEventArgs args)
        {
            if (noUpdate)
                return;

            noUpdate = true;

            if (args.AddedPlugs.Count == 0)
                SelectedIndex = -1;
            else
                SelectedKey = args.AddedPlugs[0];

            noUpdate = false;
        }

        private void Unplugged(object sender, PlugEventArgs args)
        {
            Items.Remove(args.PlugInfo);
        }

        public SlotInfo Slot { get; private set; }
    }
}

